package com.shycloud.mido.member.controller;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shycloud.common.minio.service.MinioTemplate;
import com.shycloud.mido.common.core.util.R;
import com.shycloud.mido.common.sms.sdk.CloopenSmsSDK;
import com.shycloud.mido.member.api.entity.BasicAppShoppingOrder;
import com.shycloud.mido.member.api.entity.Member;
import com.shycloud.mido.member.api.entity.SmApiLog;
import com.shycloud.mido.member.api.entity.SmMemberActivateStatistics;
import com.shycloud.mido.member.api.util.EncryptUtil;
import com.shycloud.mido.member.api.vo.AppShoppingOrderVO;
import com.shycloud.mido.member.api.vo.WeekDataMemberVO;
import com.shycloud.mido.member.mapper.MemberMapper;
import com.shycloud.mido.member.mapper.SmMemberActivateStatisticsMapper;
import com.shycloud.mido.member.service.AppShoppingMallService;
import com.shycloud.mido.member.service.BaseMusicAuditionCodeService;
import com.shycloud.mido.member.service.MemberServiceV2;
import com.shycloud.mido.member.service.SmApiLogService;
import com.shycloud.mido.member.service.SmMemberActivateStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 上音社图书绑定接口
 *
 * @author nianhua.jiang
 * @date 2020-12-01 15:39
 */
@RestController
@AllArgsConstructor
@RequestMapping("/webapi")
@Slf4j
@Api
public class WebApiController {

	/** 扫描有声图书业务 service */
	private BaseMusicAuditionCodeService auditionCodeService;
	/** 上音社传输 data 记录 service */
	private SmApiLogService smApiLogService;
	/** app商城服务 */
	private AppShoppingMallService shoppingMallService;

	private MemberServiceV2 memberService;
	/** 用户模块 mapper */
	private final MemberMapper memberMapper;
	/** 七牛云业务工具类 */
	private MinioTemplate minioTemplate;
	/** 硬件权限数据统计表 service */
	private final SmMemberActivateStatisticsService activateStatisticsService;
	/** 硬件权限数据统计表 mapper */
	private final SmMemberActivateStatisticsMapper activateStatisticsMapper;
	private final RedisTemplate redisTemplate;
	private final CloopenSmsSDK cloopenSmsSDK;

	private static Log logger = LogFactory.getLog(WebApiController.class);

	/**
	 * 上音社图书绑定接口
	 *
	 * @param data 加密信息
	 * @return
	 */
	@PostMapping("/datapush")
	public Map<String, String> dataPush(@RequestParam(value = "data") String data) {

		Map<String, String> map = new HashMap<>();

		if (data == null || data.isEmpty()) {
			map.put("msg", "请求参数为空！");
			return map;
		}

		try {

			data = URLDecoder.decode(URLEncoder.encode(data, "UTF-8").replace("+", "%2B"), "UTF-8");
			SmApiLog log = new SmApiLog();
			log.setData(data);
			smApiLogService.save(log);
			// AES128解密
			String strAes = EncryptUtil.decryptBase64(data);
			// 转化为json对象
			JSONObject json = JSONUtil.parseObj(strAes);
			// 用户账号（手机号）
			String userPhone = json.get("userID").toString();
			// 图书编码
			String bookNumber = json.get("bookNumber").toString();

			boolean ret = auditionCodeService.bindSyBook(userPhone, bookNumber);
			if (!ret) {
				map.put("msg", "绑定失败!");
			}

			logger.info("开始创建上音扫码订单 ========>");

			//创建一个订单
			AppShoppingOrderVO orderVO = new AppShoppingOrderVO();
			List<BasicAppShoppingOrder> shoppingItems = new ArrayList<>();
			BasicAppShoppingOrder shoppingOrder = new BasicAppShoppingOrder();
			shoppingOrder.setSyId(bookNumber);
			shoppingOrder.setCreateTime(LocalDateTime.now());
			shoppingOrder.setQuantity(1);
			//扫码获得，不设置快乐贝价格
			//shoppingOrder.setUnitGoldPrice(0);
			shoppingItems.add(shoppingOrder);
			orderVO.setShoppingItems(shoppingItems);
			orderVO.setFromSy(true);
			orderVO.setUserPhone(Long.valueOf(userPhone));
			shoppingMallService.createOrder(orderVO);
		} catch (Exception e) {
			map.put("msg", "处理发生异常!");
			logger.error(e.getMessage(), e);
			logger.error("扫码处理异常！");
			return map;
		}
		map.put("msg", "ok");
		return map;
	}

	@ApiOperation(value = "获取注册人数统计", tags = "后台主页数据统计")
	@GetMapping("getMemberCount")
	public R getMemberCount() {

		List<Map<String, Object>> res = new ArrayList<>();

		Map<String, Object> resMap1 = new HashMap<>();
		Map<String, Object> resMap2 = new HashMap<>();
		Map<String, Object> resMap3 = new HashMap<>();

		//APP新注册人数
		resMap1.put("count", memberService.count(new QueryWrapper<Member>().eq("is_old", 0)));
		resMap1.put("name", "APP新注册人数");

		res.add(resMap1);

		//咪哆迁移人数
		resMap2.put("count", memberService.count(new QueryWrapper<Member>().eq("is_old", 1)));
		resMap2.put("name", "咪哆迁移人数");

		res.add(resMap2);

		//上音社引流人数
		resMap3.put("count", memberService.count(new QueryWrapper<Member>().eq("is_old", 3)));
		resMap3.put("name", "上音社引流人数");

		res.add(resMap3);

		return new R(res);

	}

	@GetMapping("getMasterCount")
	public R getMasterCount(String dateTime) {

		if (StringUtils.isEmpty(dateTime)) {
			dateTime = "2020-10-01";
		}

		List<Map<String, Object>> res = new ArrayList<>();
		Map<String, Object> resMap1 = new HashMap<>(2);
		Map<String, Object> resMap2 = new HashMap<>(2);
		Map<String, Object> resMap3 = new HashMap<>(2);
		//新用户使用硬件码数量
		resMap1.put("count", memberMapper.memberActvCodeUseCount(dateTime, "0"));
		resMap1.put("name", "新用户使用硬件码数量(长期)");
		res.add(resMap1);
		//迁移用户使用硬件码数量
		resMap2.put("count", memberMapper.memberActvCodeUseCount(dateTime, "1"));
		resMap2.put("name", "迁移用户使用硬件码数量");
		res.add(resMap2);
		//新用户使用硬件码数量
		resMap3.put("count", memberMapper.memberActvCodeUseCountTY(dateTime, "0"));
		resMap3.put("name", "新用户使用硬件码数量(体验,租赁)");
		res.add(resMap3);

		return new R(res);
	}

	@Cacheable(value = "countDetail", key = "#root.methodName")
	@ApiOperation(value = "获取用户某段时间的增量", tags = "后台主页数据统计")
	@GetMapping("getCountDetail")
	public R getCountDetail() {
		return new R();
	}

	@GetMapping("delCloudResourse")
	public R delCloudResourse(String bucketName, String url) {
		String str = url.substring(0, url.indexOf("com/"));
		System.out.println(str);
		//处理 url -> key "http://nianhua-test.com/asdadadaadsad.pdf" -> "asdadadaadsad.pdf"
		String key = url.substring(str.length() + 4, url.length());
		//根据 BucketName 获取对应的域名
		try {
			minioTemplate.delete(bucketName, key);
		} catch (Exception e) {
			e.printStackTrace();
			return new R(key);
		}
		return new R(key);
	}

	/**
	 * 硬件账号活跃统计接口
	 *
	 * @param startTime 开始时间
	 * @param endTime   结束时间
	 * @return {@link R}
	 * @author nianhua.jiang
	 * @date 2021/11/19 9:07
	 */
	@GetMapping("getActiveMemberCount")
	@Cacheable(value = "getActiveMemberCount", key = "'getActiveMemberCount'+#startTime+'_'+#endTime")
	public R getActiveMemberCount(String startTime, String endTime) {

		if (StringUtils.isEmpty(startTime)) {
			startTime = "2021-10-01";
		}
		if (StringUtils.isEmpty(endTime)) {
			endTime = "2099-12-31";
		}

		List<Map<String, Object>> res = new ArrayList<>(2);
		Map<String, Object> resMap1 = new HashMap<>(2);
		Map<String, Object> resMap2 = new HashMap<>(2);

		//老用户活跃数量
		resMap1.put("count", activateStatisticsMapper.getActiveMemberCount("1", startTime, endTime));
		resMap1.put("name", "斑马老用户活跃数量");
		res.add(resMap1);
		//新用户活跃数量
		resMap2.put("count", activateStatisticsMapper.getActiveMemberCount("0", startTime, endTime));
		resMap2.put("name", "斑马新用户活跃数量");
		res.add(resMap2);

		return new R(res);
	}

	/** ============= 以下针对数据统计接口存在的数据查询内容做出的提前查询，每日凌晨 1点 定期查询 ================== */
	@GetMapping("batchAddMemberMaster")
	public R batchAddMemberMaster() {
		//查询权限非永久的用户
		List<SmMemberActivateStatistics> acts = memberMapper.getMasterMember();
		//循环计算 end_time mybatis plus 不支持语法，暂时给注掉，用 java 代码实现
		for (SmMemberActivateStatistics act : acts) {
			act.setEndTime(act.getStartTime().plusDays(act.getDuration()));
			if (StringUtils.isBlank(act.getIsOld())) {
				act.setIsOld("0");
			}
		}
		//删除原有数据
		activateStatisticsService.remove(new QueryWrapper<SmMemberActivateStatistics>().eq("is_forever", "0"));
		//删除redis缓存
		redisTemplate.delete("getActiveMemberCount");
		return new R(activateStatisticsService.saveBatch(acts));
	}

	@GetMapping("batchAddMemberMasterForever")
	public R batchAddMemberMasterForever() {
		List<SmMemberActivateStatistics> acts = memberMapper.getMasterMemberForever();
		return new R(activateStatisticsService.saveBatch(acts));
	}

	/**
	 * 指定手机号发送短信接口
	 *
	 * @param phone      手机号
	 * @param templateId 模板ID
	 * @return {@link R}
	 * @author nianhua.jiang
	 * @date 2021/12/1 11:07
	 */
	@SneakyThrows
	@GetMapping("sendShortMsg")
	public R sendShortMsg(String phone, String templateId, String[] datas) {
		return new R(cloopenSmsSDK.sendTemplateSMS(phone, templateId, datas));
	}

	/** ============= 以下针对 shardingSphere 报错：Must have sharding column with subquery. 做出的不成熟解决方案 通过 feign 方式实现 ===== */
	@GetMapping("getHomeworkDoneCountRank")
	public Integer getHomeworkDoneCountRank(String weekId, String memberId) {
		return memberMapper.getHomeworkDoneCountRank(weekId, memberId);
	}

	@GetMapping("pageMemberListByWeekV3")
	public List<WeekDataMemberVO> pageMemberListByWeekV3(Integer current, Integer size) {
		IPage<WeekDataMemberVO> weekDataMemberVOIPage = memberMapper.pageMemberListByWeekV3(new Page<>(current, size));
		return weekDataMemberVOIPage.getRecords();
	}

}
